package com.ruoyi.system.xcenter.adapter;

import cn.hutool.crypto.digest.DigestUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.common.json.JSON;
import com.ruoyi.common.json.JSONObject;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.security.Md5Utils;
import com.ruoyi.system.domain.DataxBizOrder;
import com.ruoyi.system.mapper.DataxBizOrderMapper;
import com.ruoyi.system.xcenter.EPContext;
import com.ruoyi.system.xcenter.WrapperAdapter;
import com.ruoyi.system.xcenter.exception.DataXException;
import com.ruoyi.system.xcenter.utils.DataxCacheUtil;
import com.ruoyi.system.xcenter.utils.ParkcodeMapConstants;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.stereotype.Component;

import java.util.Date;

@Slf4j
@Component
@EnableScheduling
public class Jieshun2XindianAdapter implements WrapperAdapter {

    private EPContext ctx;

    @Autowired
    private DataxBizOrderMapper bizOrderMapper;

    /**
     * 数据转封装器
     * @param data
     * @param ctx
     * @param type 1:停车位同步；2：入场；3：出场
     * @return
     */
    @Override
    public Object wrapperData(Object data, EPContext ctx, Integer type) throws Exception {
        this.ctx = ctx;
        Object req = new JSONObject();
        ctx.getXchangeLog().setClientEndReq((String) data);
        switch (type){
            case 1:
                req = wrapperParkSpaceXindian((String) data);
                break;
            case 2:
                req = wrapperParkInXindian((String) data);
                break;
            case 3:
                req = wrapperParkOutXindian((String) data);
                break;
            case 4:
                // 订单接入-限制指定商户号-订单
                req = wrapperParkOrderXindian((String) data);
                break;
            default:
                log.warn("未知的数据接入类型");
                break;
        }

        return req;
    }

    /**
     * 订单信息转换
     * @return
     * @throws Exception
     */
    private Object wrapperParkOrderXindian(String body) throws Exception{
        JSONObject.JSONArray result = new JSONObject.JSONArray();
        JSONObject json = JSON.unmarshal(body,JSONObject.class);
        String dataItemStr = json.getStr("dataItems");
        JSONObject.JSONArray dataItems = JSON.unmarshal(dataItemStr,JSONObject.JSONArray.class);
        JSONObject.JSONArray tmp = new JSONObject.JSONArray();
        for (Object dataItem : dataItems) {
            if(!tmp.contains(dataItem)){
                tmp.add(dataItem);
            }
        }
        for (Object dataItem : tmp) {
            JSONObject jsonItem = (JSONObject)dataItem;
            String parkCode = jsonItem.getStr("parkCode");
            String businesserCode = jsonItem.getStr("businesserCode");
            if(!ParkcodeMapConstants.BUSINESS_NO.equals(businesserCode)&&parkCode.equals("p221096492")){
                throw new DataXException("不支持的商户订单扣款,"+businesserCode);
            }
            DataxBizOrder bizOrder = new DataxBizOrder();
            bizOrder.setParkName(jsonItem.getStr("parkName"));
            bizOrder.setType(3); // 此处捷顺对信电用：代扣
            bizOrder.setFlag(0); // 初始订单标记为待确认
            bizOrder.setStatus(2); // 支付成功-捷顺推送成功的订单
            bizOrder.setOrderTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",jsonItem.getStr("orderCreateTime")));
            bizOrder.setServiceFee(jsonItem.getInt("serviceFee"));
            bizOrder.setTotalFee(jsonItem.getInt("totalFee"));
            bizOrder.setGateNo(ParkcodeMapConstants.parkCodeMap.get(parkCode));
            bizOrder.setLeaveTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",jsonItem.getStr("endTime")));
            bizOrder.setPlateNo(jsonItem.getStr("carNumber"));
            bizOrder.setInTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",jsonItem.getStr("inTime")));
            bizOrder.setPayNo(jsonItem.getStr(""));
            bizOrder.setPayTime(DateUtils.dateTime("yyyy-MM-dd HH:mm:ss",jsonItem.getStr("tradeTime")));
            bizOrder.setTradeNo(json.getStr("orderNo"));
            bizOrderMapper.insertDataxBizOrder(bizOrder);
            // TODO 构造信电订单扣费请求
            String extBusinessId = Md5Utils.hash(jsonItem.getStr("carNumber")+jsonItem.getStr("inTime"));
            JSONObject parkOutJson = new JSONObject();
            parkOutJson.put("parkpotId", ParkcodeMapConstants.parkCodeMap.get(parkCode));
            parkOutJson.put("extBusinessId",extBusinessId);
            parkOutJson.put("paymentTotal",jsonItem.getInt("serviceFee"));
            parkOutJson.put("totalFee",jsonItem.getInt("totalFee"));
            parkOutJson.put("outTradeNo",json.getStr("orderNo"));
            parkOutJson.put("outTradeTime",jsonItem.getStr("orderCreateTime"));
            parkOutJson.put("autoPayType","0");
            parkOutJson.put("gateno","");

            result.add(parkOutJson);
        }
        return result;
    }


    /**
     * 捷顺>信电数据转换--车位信息变化
     * @param body
     * @return
     */
    private Object wrapperParkSpaceXindian(String body) throws Exception {
        JSONObject.JSONArray result = new JSONObject.JSONArray();
        JSONObject json = JSON.unmarshal(body,JSONObject.class);
        String dataItemStr = json.getStr("dataItems");
        JSONObject.JSONArray dataItems = JSON.unmarshal(dataItemStr,JSONObject.JSONArray.class);
        JSONObject.JSONArray tmp = new JSONObject.JSONArray();
        for (Object dataItem : dataItems) {
            if(!tmp.contains(dataItem)){
                tmp.add(dataItem);
            }
        }
        for (Object dataItem : tmp) {
            JSONObject jsonItem = (JSONObject)dataItem;
            String parkCode = jsonItem.getStr("parkCode");
            DataxCacheUtil.PARK_SPACE.put(parkCode,jsonItem.getInt("remainSpace"));
            JSONObject parkOutJson = new JSONObject();
            parkOutJson.put("parkpotId", ParkcodeMapConstants.parkCodeMap.get(parkCode));
            parkOutJson.put("freeParklotCount",jsonItem.getInt("remainSpace"));
            result.add(parkOutJson);
        }
        return result;
    }

    /**
     * 捷顺>信电数据转换--车辆离场
     * @param body
     * @return
     */
    private Object wrapperParkOutXindian(String body) throws Exception {
        JSONObject.JSONArray result = new JSONObject.JSONArray();
        JSONObject json = JSON.unmarshal(body,JSONObject.class);
        String dataItemStr = json.getStr("dataItems");
        JSONObject.JSONArray dataItems = JSON.unmarshal(dataItemStr,JSONObject.JSONArray.class);
        JSONObject.JSONArray tmp = new JSONObject.JSONArray();
        for (Object dataItem : dataItems) {
            if(!tmp.contains(dataItem)){
                tmp.add(dataItem);
            }
        }
        for (Object dataItem : tmp) {
            JSONObject jsonItem = (JSONObject)dataItem;
            String parkCode = jsonItem.getStr("parkCode");
            JSONObject parkOutJson = new JSONObject();
            String extBusinessId = Md5Utils.hash(jsonItem.getStr("carNumber")+jsonItem.getStr("inTime"));
            parkOutJson.put("parkpotId",ParkcodeMapConstants.parkCodeMap.get(parkCode));
            parkOutJson.put("extBusinessId",extBusinessId);
            parkOutJson.put("parkTime",jsonItem.get("inTime"));
            parkOutJson.put("leaveTime",jsonItem.get("outTime"));

            parkOutJson.put("plateNo",JSON.unmarshal(jsonItem.getStr("vehicleInfo"),JSONObject.class).getStr("plateNo").replace("-",""));
            parkOutJson.put("plateType",plateTypeConvert(JSON.unmarshal(jsonItem.getStr("vehicleInfo"),JSONObject.class).getStr("plateColor")));
            parkOutJson.put("parkBusinessType",11);
            parkOutJson.put("freeParklotCount",DataxCacheUtil.PARK_SPACE.get(parkCode));
            parkOutJson.put("leaveBusinessType",21);
            String moneyStr = jsonItem.getStr("ysMoney")!=null?jsonItem.getStr("ysMoney"):"0";
            Float money = Float.valueOf(moneyStr)*100;
            parkOutJson.put("paymentTotal",money.intValue());
            parkOutJson.put("outImgUrl",ossUrlConvert(body,jsonItem.getStr("outCarPhoto")));
            parkOutJson.put("outImgTaketime",jsonItem.getStr("outTime"));
            parkOutJson.put("plateColor",JSON.unmarshal(jsonItem.getStr("vehicleInfo"),JSONObject.class).getStr("plateColor"));

            result.add(parkOutJson);
        }
        return result;
    }

    /**
     * 捷顺>信电数据转换--车辆进场
     * @param body
     * @return
     */
    private Object wrapperParkInXindian(String body) throws Exception {
        JSONObject.JSONArray result = new JSONObject.JSONArray();
        JSONObject json = JSON.unmarshal(body,JSONObject.class);
        String dataItemStr = json.getStr("dataItems");
        JSONObject.JSONArray dataItems = JSON.unmarshal(dataItemStr,JSONObject.JSONArray.class);
        JSONObject.JSONArray tmp = new JSONObject.JSONArray();
        for (Object dataItem : dataItems) {
            if(!tmp.contains(dataItem)){
                tmp.add(dataItem);
            }
        }
        for (Object dataItem : tmp) {
            JSONObject jsonItem = (JSONObject)dataItem;
            String parkCode = jsonItem.getStr("parkCode");
            JSONObject parkOutJson = new JSONObject();
            String extBusinessId = Md5Utils.hash(jsonItem.getStr("carNumber")+jsonItem.getStr("inTime"));
            parkOutJson.put("parkpotId",ParkcodeMapConstants.parkCodeMap.get(parkCode));
            parkOutJson.put("extBusinessId",extBusinessId);
            parkOutJson.put("parkTime",jsonItem.get("inTime"));
            parkOutJson.put("plateNo",JSON.unmarshal(jsonItem.getStr("vehicleInfo"),JSONObject.class).getStr("plateNo").replace("-",""));
            parkOutJson.put("plateColor",JSON.unmarshal(jsonItem.getStr("vehicleInfo"),JSONObject.class).getStr("plateColor"));
            parkOutJson.put("plateType",plateTypeConvert(JSON.unmarshal(jsonItem.getStr("vehicleInfo"),JSONObject.class).getStr("plateColor")));
            parkOutJson.put("parkBusinessType",11);
            parkOutJson.put("freeParklotCount",DataxCacheUtil.PARK_SPACE.get(parkCode));
            parkOutJson.put("inImgUrl",ossUrlConvert(body,jsonItem.getStr("inCarPhoto")));
            parkOutJson.put("inImgTaketime",jsonItem.get("inTime"));
            result.add(parkOutJson);
        }
        return result;
    }



    private String plateTypeConvert(String plateColor){
        switch (plateColor){
            case "GREEN":
                return "51";
            case "YELLOW":
                return "01";
            case "BLUE":
                return "02";
            case "WHITE":
                return "02";
            case "BLACK":
                return "02";
            default:
                return "02";
        }
    }

    /**
     * "pno":"ESESZY","sn":"C7EEBBD4F716C1EC9B8F4542C98C7BA0","tn":"-2","ts":"20221008170700801","ve":"1.0
     * sn=md5(secret+ts+dataItems) 大写
     * @param req
     * @return
     * @throws Exception
     */
    private String ossUrlConvert(String req,String filePath) throws Exception {
        JSONObject json = new JSONObject();
        json.put("pno",JSON.unmarshal(req,JSONObject.class).getStr("pno"));
        json.put("tn",tokenRefresh(ctx.getClient().getParkNo()));
        String timestamp = DateUtils.parseDateToStr("yyyyMMddHHmmssSSS",new Date());
        json.put("ts",timestamp);
        json.put("ve",JSON.unmarshal(req,JSONObject.class).getStr("ve"));
        JSONObject item = new JSONObject();
        item.put("filePath",filePath);
        JSONObject.JSONArray arr = new JSONObject.JSONArray();
        arr.add(item);
        json.put("dataItems",JSONUtil.toJsonStr(arr));
        String sign = DigestUtil.md5Hex(this.ctx.getClient().getAccountPwdUp()+timestamp+JSONUtil.toJsonStr(arr)).toUpperCase();
        json.put("sn",sign);
        String resp = HttpUtil.post(this.ctx.getClient().getDataDownloadUrl() + "/pic/picSearchUrl", JSON.marshal(json));
        JSONObject unmarshal = JSON.unmarshal(resp, JSONObject.class);
        if(unmarshal.getInt("resultCode")!=0){
            return filePath;
        }
        String url = ((JSONObject)unmarshal.getArr("dataItems").get(0)).getStr("image");
        return url;
    }

    private String tokenRefresh(String parkNo){
        return DataxCacheUtil.PARK_TOKEN.get(parkNo,false,()->{
            JSONObject json = new JSONObject();
            json.put("pno",this.ctx.getClient().getAccountUserUp());
            json.put("secret",this.ctx.getClient().getAccountPwdUp());
//            json.put("pno","TESTAPI");
//            json.put("secret","ffdae7eb6cd04ed0b728111d8da43050");
            String res = HttpUtil.post(this.ctx.getClient().getDataDownloadUrl() + "/login", JSON.marshal(json));
//            String res = HttpUtil.post("http://jhtdc.jslife.com.cn/api/login", JSON.marshal(json));
            JSONObject jsonObject = JSON.unmarshal(res, JSONObject.class);
            String token = jsonObject.getStr("tn");
            DataxCacheUtil.PARK_TOKEN.put(parkNo,token);
            return token ;
        });
    }


}
